/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import data.DataManager;
import data.Professor;
import data.Room;
import data.Student;
import data.TimeSlot;
import java.util.List;
import java.util.Random;
import objective.AllDifferent;
import objective.AandBnotSameValueAtDifferentIndex;
import objective.AnotDuplicateB;
import objective.ObjectiveSystem;
import objective.XInSet;
import objective.XequalY;
import objective.XnotInSet;

/**
 *
 * @author daz
 */
public class Runner {

    private static List<Professor> listProfessors;
    private static List<TimeSlot> listTimeSlots;
    private static List<Room> listRooms;
    private static List<Student> listStudents;
    private static Random random = new Random();

    private static void readData() {
        DataManager dataManager = new DataManager();
        listTimeSlots = dataManager.getListTimeSlot();
        listProfessors = dataManager.getListProfessors();

        for (Professor p : listProfessors) {
            p.setListDomains(dataManager.getListProfessorDomain(p.getId()));
            //add time available
        }
        listRooms = dataManager.getListRooms();
        listStudents = dataManager.getListStudents();
    }

    private static void model() {
        int numberProfessors = listProfessors.size();
        int numberTimeSlot = listTimeSlots.size();
        int numberRooms = listRooms.size();
        int numberStudents = listStudents.size();
        int numberInHustMustPresent = 2;
        int numberJuryMembers = 5;
        int[] listRoomIds = new int[numberRooms];
        int[] listTimeIds = new int[numberTimeSlot];
        Solution[] solutions = new Solution[numberStudents];
        for (int i = 0; i < numberStudents; i++) {
            Student student = listStudents.get(i);
            Room room = listRooms.get(random.nextInt(numberRooms));
            TimeSlot timeSlot = listTimeSlots.get(random.nextInt(numberTimeSlot));
            Professor[] juryMembers = new Professor[numberJuryMembers];
            for (int j = 0; j < numberJuryMembers; j++) {
                juryMembers[i] = listProfessors.get(random.nextInt(numberProfessors));
            }
            solutions[i] = new Solution(student, room, timeSlot, juryMembers);
            listRoomIds[i] = solutions[i].getRoomId();
            listTimeIds[i] = solutions[i].getTimeId();
        }

        ObjectiveSystem system = new ObjectiveSystem();
        for (int i = 0; i < numberStudents; i++) {
            
            //C1: members of jury must be different
            system.post(new AllDifferent(solutions[i].getJury()));
            //C2: supervisor not in jury
            system.post(new XnotInSet(solutions[i].getSupervisor(), solutions[i].getJury()));
            //C3: 2 reviewers present
            system.post(new XInSet(solutions[i].getReviewers1(), solutions[i].getJury()));
            system.post(new XInSet(solutions[i].getReviewers2(), solutions[i].getJury()));
            //C4: number in HUST must be J
            system.post(new XequalY(numberInHustMustPresent, solutions[i].getNumberInHusts()));
            //C5: defense time must in professor availabe time
            for (int j = 0; j < solutions[i].getNumberJuryMembers(); j++) {
                int professor = solutions[i].getJury()[j];
                system.post(new XInSet(solutions[i].getTimeId(), solutions[i].getProfessorTimeAvailable(professor)));
            }
            //C6: subject defense must be in professor domain
            for (int j = 0; j < solutions[i].getNumberJuryMembers(); j++) {
                int professor = solutions[i].getJury()[j];
                system.post(new XInSet(solutions[i].getDomain(), solutions[i].getProfessorDomain(professor)));
            }
        }
        //C7: 1 room cant take place 2 defenses at the same time
        system.post(new AandBnotSameValueAtDifferentIndex(listRoomIds, listTimeIds));
        //C8: 1 professor cant attend 2 defenses at the same time
        for (int i = 0; i < numberStudents; i++) {
            for (int j = 0; j < numberStudents; j++) {
                if (i != j && listTimeIds[i] == listTimeIds[j]) {
                    system.post(new AnotDuplicateB(solutions[i].getJury(), solutions[j].getJury()));
                }
            }
        }
        system.close();
    }

    public static void main(String[] args) {
        readData();
        model();
    }
}
